#include "Form_EditorSpace.h"

#include "QMdiSubWindow"
#include "QKeyEvent"

#include "Widget/Widget_Base_MainWindow.h"
#include "Form_WidgetBox.h"
#include "Form_PropertyEditor.h"

#include "GlobalMsg.h"
#include "QScrollBar"

Form_EditorSpace::Form_EditorSpace(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form_EditorSpace)
{
    ui->setupUi(this);

    //初始化MdiArea
    connect(ui->mdiArea,&Widget_MdiArea::event_onResize,this,&Form_EditorSpace::event_onMdiAreaReSize); //链接MdiArea的尺寸改变信息
    connect(ui->mdiArea,&Widget_MdiArea::event_onScrollBarChange,this,&Form_EditorSpace::event_onMdiAreaScrollChange); //链接Mdiarea的滚动条改变


    //ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    //ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    this->setAttribute(Qt::WA_StyledBackground); //脱离父窗口样式的覆盖


    //加载最基础的窗体信息，并且载入到列表
    Widget_Base_MainWindow* t_mainObj = new Widget_Base_MainWindow;
    this->widgetClassMsgLsit.append({
        t_mainObj,
        t_mainObj->getWidgetInstance(),
    });



    //操作SubWindow
    this->BaseSubWindow = ui->mdiArea->addSubWindow(t_mainObj->getWidgetInstance()); //将底窗口添加到
    this->BaseSubWindow->setAttribute(Qt::WA_StyledBackground); //脱离父窗口样式的覆盖
    this->BaseSubWindow->setGeometry(t_mainObj->getWidgetInstance()->geometry()); //设置基础的宽高
    this->BaseSubWindow->move(10,10);


    //创建顶部Roi的矩形画框
    this->RoiWidget = new Form_Roi(this);
    this->RoiWidget->raise();



    //将信息插入到列表
    ui->widgetList->addBaseItem(t_mainObj->getWidgetInstance(),QIcon(":/Logo/icon/Logo/Logo_32.png"),"主窗口","QMainWidget");
    connect(ui->widgetList,&Widget_widgetList::event_onItemClick,this,&Form_EditorSpace::event_onTreeItemClick); //连接TreeWidget项目被点击

}



Form_EditorSpace::~Form_EditorSpace()
{
    delete ui;
}


//窗体尺寸被改变
void Form_EditorSpace::resizeEvent(QResizeEvent *event)
{
    //调整绘画层的区域覆盖
    QRect t_rec = ui->mdiArea->geometry();
    t_rec.setWidth(t_rec.width() - 15); //15px为滚动条的宽度
    t_rec.setHeight(t_rec.height() - 15);
    RoiWidget->setGeometry(t_rec);
}

void Form_EditorSpace::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Control) {
        ctrlDown = true;
    } else {
        QWidget::keyPressEvent(event);
    }
}

void Form_EditorSpace::keyReleaseEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Control) {
        ctrlDown = false;
    } else {
        QWidget::keyPressEvent(event);
    }
}

//分割条比例调整
void Form_EditorSpace::on_splitter_splitterMoved(int pos, int index)
{
    this->resizeEvent(nullptr);
}

//当绘画层的滚动条被改变，则立即刷新选区的位置
void Form_EditorSpace::event_onMdiAreaScrollChange(int dx, int dy)
{
    this->RoiWidget->roi_ChangeRecTopLeft(dx,dy);
    this->RoiWidget->update();
}

//MdiArea尺寸改变，修正上面绘画层的选区尺寸
void Form_EditorSpace::event_onMdiAreaReSize(QResizeEvent *resizeEvent)
{
    this->resizeEvent(nullptr);
    this->RoiWidget->update();
}



//当TreeItem被点击
void Form_EditorSpace::event_onTreeItemClick(QWidget *widget)
{
    RoiWidget->roi_ClearRec(); //清理矩形
    if(widget == nullptr) return;
    QRect t_rec = getWidgetAbsolutePos(widget);
    RoiWidget->roi_AddRec({
                           {widget,t_rec},
                           });
    this->RoiWidget->update();

    //加载属性信息
    QVector<Form_Roi::widgetRecMsg> t_widRecMsg = this->RoiWidget->roi_GetAllWidgetPtrs();
    QVector<Widget_Base*> t_objs;
    for(int a = 0;a<t_widRecMsg.length();a++){
        WidgetClassMsg t_classMsg = this->getWidgetClassMsg(t_widRecMsg[a].widget);
        if(t_classMsg.classObj != nullptr){
            t_objs.append(t_classMsg.classObj);
        }
    }
    PropertyEditorPtr->loadPropertyMsgs(t_objs,this); //加载属性信息
}



//设置对象新名称
void Form_EditorSpace::event_onObjectRename(QWidget *widget, QString newName)
{


}



//当鼠标点击了某一个位置
void Form_EditorSpace::event_onMouseDown(int x, int y,QWidget* formPtr)
{
    QWidget* t_selectWidget = nullptr;

    if(nowWidgetPluginMsg == nullptr){ //不是添加控件，只是普通的点击
        if(ctrlDown == false) this->RoiWidget->roi_ClearRec(); //清理矩形
        if(this->RoiWidget->cursor() == Qt::ArrowCursor){ //没有选区的时候，使用本地检索
            t_selectWidget = getWidgetFromPos(x,y);
        }

        if(t_selectWidget == nullptr){ //如果检索不到，则使用选择器提供的widget指针
            if(formPtr == nullptr){
                return;
            }
            else{
                t_selectWidget = formPtr;
            }
        }
        QRect t_rec = getWidgetAbsolutePos(t_selectWidget);
        this->RoiWidget->roi_AddRec({
                               {t_selectWidget,t_rec},
                               });


        ui->widgetList->selectItem(t_selectWidget);
    }
    else{ //是添加控件，准备创建新的控件信息
        QWidget* t_containerWidget = nullptr;
        WidgetClassMsg t_widMsg;

        if(formPtr != nullptr){  //检索当前的控件是否为容器
            t_widMsg = this->getWidgetClassMsg(formPtr);
            if(t_widMsg.classObj != nullptr){
                if(t_widMsg.classObj->container){
                    t_containerWidget = t_widMsg.formPtr;
                }
            }
        }

        if(t_containerWidget  == nullptr){ //如果当前选择的不是容器控件
            t_containerWidget = getContainerWidgetFromPos(x,y,t_widMsg); //自动寻找父容器
        }

        if(t_containerWidget  != nullptr){ //如果容器存在，则添加子控件
            typedef Widget_Base* (*t_funPtr)();

            t_funPtr t_getInstance = (t_funPtr)nowWidgetPluginMsg->qLibPth->resolve("getInstance");
            if(t_getInstance != nullptr){  //获取插件实例

                WidgetClassMsg t_classMsg;
                t_classMsg.classObj = t_getInstance();
                t_selectWidget = t_classMsg.classObj->getWidgetInstance();  //获取当前选择的窗口信息
                t_classMsg.formPtr = t_selectWidget;//保存当前的选择的窗口
                t_selectWidget->setObjectName(this->getUniqueName(t_selectWidget->objectName())); //设置窗体对象名
                widgetClassMsgLsit.append(t_classMsg); //将类信息存储到列表

                QRect t_parentRect = getWidgetAbsolutePos(t_containerWidget); //添加组件到编辑器主窗口
                t_selectWidget->setParent(t_containerWidget);
                t_selectWidget->move(x - t_parentRect.left() - t_classMsg.formPtr->width() / 2,y - t_parentRect.top() - t_classMsg.formPtr->height() / 2); //将控件移动到新的位置
                t_selectWidget->show();

                t_widMsg.classObj->event_onChildJoin(t_selectWidget); //通知父容器新成员加入
                ui->widgetList->addItem(t_selectWidget,nowWidgetPluginMsg->widgetMsg.pix,t_selectWidget->objectName(),nowWidgetPluginMsg->widgetMsg.className);

                //刷新选框显示
                this->RoiWidget->roi_ClearRec(); //清理矩形
                QRect t_rec = getWidgetAbsolutePos(t_selectWidget);
                this->RoiWidget->roi_AddRec({
                                       {t_selectWidget,t_rec},
                                       });
                this->RoiWidget->update();


            }
        }

        widgetBoxPtr->selectItem(0); //空间箱置为默认选项
        nowWidgetPluginMsg = nullptr; //置空当前选择的控件
    }



    QVector<Form_Roi::widgetRecMsg> t_widRecMsg = this->RoiWidget->roi_GetAllWidgetPtrs();
    QVector<Widget_Base*> t_objs;
    for(int a = 0;a<t_widRecMsg.length();a++){
        WidgetClassMsg t_classMsg = this->getWidgetClassMsg(t_widRecMsg[a].widget);
        if(t_classMsg.classObj != nullptr){
            t_objs.append(t_classMsg.classObj);
        }
    }
    PropertyEditorPtr->loadPropertyMsgs(t_objs,this); //加载属性信息
}



//当Widget尺寸选区大小被更改
void Form_EditorSpace::event_onWidgetSizeChange(QWidget *widget, QRect changeRect)
{
    if(widget == nullptr) return;

    QRect t_rec;
    if(widget == this->BaseSubWindow->widget()){ //判断是否为基准窗口,如果是基准窗口，则直接调整基准窗口的位置
        t_rec = ui->mdiArea->subWindowList()[0]->geometry();
        ui->mdiArea->subWindowList()[0]->setGeometry(QRect(t_rec.left() + changeRect.left(),t_rec.top() + changeRect.top(),t_rec.width() + changeRect.width(),t_rec.height() + changeRect.height()));
    }
    else{ //不是基准窗口，则为普通控件
        t_rec = widget->geometry();

        WidgetClassMsg t_msg = getWidgetClassMsg(widget);
        if(t_msg.classObj != nullptr){
            t_msg.classObj->event_onWidgetSizeChange(QRect(t_rec.left() + changeRect.left(),t_rec.top() + changeRect.top(),t_rec.width() + changeRect.width(),t_rec.height() + changeRect.height()));
        }


        //widget->setGeometry();
    }
    this->RoiWidget->roi_ChangeRecTopLeft(changeRect.left(),changeRect.top());

    //若是调整大小的信息，则立即刷新信息
    if(changeRect.width() != 0 || changeRect.height() != 0){
        this->RoiWidget->roi_ClearRec(); //清理矩形
        QRect t_rec = getWidgetAbsolutePos(widget);
        this->RoiWidget->roi_AddRec({
                               {widget,t_rec},
                               });
    }

    PropertyEditorPtr->showProertyMsg(); //刷新信息
}





//查询当前的窗体相对于基准窗口的位置信息
QRect Form_EditorSpace::getWidgetAbsolutePos(QWidget *form)
{
    QWidget* t_form = form;
    int t_left = this->BaseSubWindow->pos().x(),t_top = this->BaseSubWindow->y(),t_width = form->width(),t_height = form->height();

    do{
        if(t_form == this->BaseSubWindow){
            break;
        }
        t_left += t_form->pos().x();
        t_top += t_form->pos().y();
        t_form = t_form->parentWidget();
    }
    while(t_form != nullptr);
    return QRect(t_left,t_top,t_width,t_height); //返回相对于主窗体的相对位置
}


//工具坐标获取窗体指针
QWidget *Form_EditorSpace::getWidgetFromPos(int x, int y)
{
    for(int a = this->widgetClassMsgLsit.length() - 1;a >= 0;a--){
        QRect t_rec = this->getWidgetAbsolutePos(this->widgetClassMsgLsit[a].formPtr);
        if(x > t_rec.left() && x < t_rec.left() + t_rec.width() &&
            y > t_rec.top() && y < t_rec.top() + t_rec.height()){
            return this->widgetClassMsgLsit[a].formPtr;
        }
    }
    return nullptr;
}



//根据坐标获取容器窗体指针
QWidget *Form_EditorSpace::getContainerWidgetFromPos(int x, int y,WidgetClassMsg& wMsg)
{
    for(int a = this->widgetClassMsgLsit.length() - 1;a >= 0;a--){
        if(this->widgetClassMsgLsit[a].classObj->container){ //判断是否为容器，如果是容器，则判断是否在矩形区域内
            QRect t_rec = this->getWidgetAbsolutePos(this->widgetClassMsgLsit[a].formPtr);
            if(x > t_rec.left() && x < t_rec.left() + t_rec.width() &&
                y > t_rec.top() && y < t_rec.top() + t_rec.height()){
                wMsg = this->widgetClassMsgLsit[a];
                return this->widgetClassMsgLsit[a].formPtr;
            }
        }
    }
    return nullptr;
}



//根据窗口指针获取类信息
Form_EditorSpace::WidgetClassMsg Form_EditorSpace::getWidgetClassMsg(QWidget *form)
{
    for(int a = this->widgetClassMsgLsit.length() - 1;a >= 0;a--){
        if(this->widgetClassMsgLsit[a].formPtr == form){
            return this->widgetClassMsgLsit[a];
        }
    }
    return Form_EditorSpace::WidgetClassMsg(); //没有则返回空信息
}


//根据当前的对象名获取唯一的对象名称
QString Form_EditorSpace::getUniqueName(QString name)
{
    if(name.isEmpty()){
        name = "Widget";
    }

    bool t_can;
    int t_num = 0;
    QString t_newNumber = name;
    do{
        t_can = true;
        for(auto value : this->widgetClassMsgLsit){
            if(t_newNumber == value.formPtr->objectName()){
                t_can = false;
                break;
            }
        }
        if(t_can == false){
            ++t_num;
            t_newNumber = name + QString::number(t_num);
        }
        else{
            break;
        }
    }
    while(true);
    return t_newNumber;
}
